<?php
/**
 * Created by PhpStorm.
 * User: refar
 * Date: 19-11-30
 * Time: 下午4:17
 */

namespace app\v1\controller;
use think\Db;
use think\Exception;
use ext\MailTemplate;
use think\Log;

class Flow extends Common {
    public function test(){ 
        Db::table('ems_my_borrow')
        ->where('ems_request_id', "R100010")
        ->update([
            'borrow_num' => Db::raw('borrow_num - ' . 1),
            'is_delete' => Db::raw('CASE WHEN (borrow_num - ' . 1 . ') = 0 THEN 1 ELSE 0 END'),
            'request_status' => 0
        ]);   
    }

    public function JudgeReturnNum(){
        $ems_request_id = $this->request->param('ems_request_id');
        $ems_request_ids=json_decode($ems_request_id,true);
        $return_num = $this->request->param('return_num');
        if (empty($ems_request_ids)) {
            return apiResponse(ERROR, '参数错误：ems_request_id不能为空');
        }
        $count=Db::table("ems_my_borrow")
            ->whereIn("ems_request_id", $ems_request_ids)
            ->where("borrow_num", $return_num)
            ->count();
        if($count==count($ems_request_ids)){
            return apiResponse(SUCCESS, '当前样品全部归还入库',["type"=>1]);
        }else{
            $less_count=Db::table("ems_my_borrow")
                ->whereIn("ems_request_id", $ems_request_ids)
                ->where("borrow_num",'>=', $return_num)
                ->count();
            if($less_count==count($ems_request_ids)){
                return apiResponse(SUCCESS, '当前归还入库数量少于借出数量,请知晓',["type"=>2]);
            }else{
                return apiResponse(SUCCESS, '归还数量超过了某个选中样实际借出数量',["type"=>3]);
            }
        }


    }
    /**
     * 获取我的借用申请列表（分页）
     * @return \think\response\Json
     */
    public function getBorrowList()
    {
        $userId = $this->loginUser['ems'];
//
//        // 获取分页参数
//        $offset = intval($this->request->param('offset', 0));
//        $limit = intval($this->request->param('limit', 10));
//
//        // 参数验证
//        if ($offset < 0) {
//            $offset = 0;
//        }
//        if ($limit <= 0 || $limit > 100) {
//            $limit = 10; // 默认每页10条，最大100条
//        }
        
        try {
            // 查询总数
//            $total = Db::table("ems_my_borrow")
//                ->where([
//                    'user_id' => $userId,
//                    'is_delete' => 0,
//                    'request_status' => BORROW_REVIEW
//                ])
//                ->count();
                
            // 查询分页数据
            $res = Db::table("ems_my_borrow")
                ->where([
                    'user_id' => $userId,
                    'is_delete' => 0,
                    'request_status' => BORROW_REVIEW
                ])
//                ->limit($offset, $limit)
                ->select();
//
//            $result = [
//                'list' => $res,
//                'total' => $total,
//                'offset' => $offset,
//                'limit' => $limit
//            ];
            
            return apiResponse(SUCCESS, '[Machine][getBorrowList] success', $res);
        } catch (Exception $e) {
            Log::record('[Machine][getBorrowList] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }
    }


    /**
     * 取消借用申请
     * @return \think\response\Json
     */
    public function cancelBorrowList(){
        $ems_request_id = $this->request->param('ems_request_id');


        
        // 开启事务
        Db::startTrans();
        try {
            // 查询借用记录
            $borrowRecord = Db::table("ems_my_borrow")
                ->where("ems_request_id", $ems_request_id)
                ->find();
                
            if (empty($borrowRecord)) {
                Db::rollback();
                Log::record('[Flow][cancelBorrowList] borrow record not found, ems_request_id: ' . $ems_request_id);
                return apiResponse(ERROR, '借用记录不存在');
            }
            $old_borrow_data=Db::table("ems_main_engine")
                ->field("used_num")
                ->where("fixed_no", $borrowRecord['fixed_no'])
                ->find();

            $remain_num=$old_borrow_data["used_num"]-$borrowRecord["borrow_num"];
            if($remain_num<0){
                Db::rollback();
                Log::record('[Flow][cancelBorrowList] remain_num: ' . $remain_num);
                return apiResponse(ERROR, '使用数比借用数小');
            }elseif ($remain_num ==0){
                $model_status=IN_STORE;
            }elseif($remain_num>0){
                $model_status=PART_USING;
            }
            // 更新主设备表的库存
            $updateResult = Db::table("ems_main_engine")
                ->where("fixed_no", $borrowRecord['fixed_no'])
                ->update([
                    'inventory_num' => Db::raw('inventory_num + ' . intval($borrowRecord["borrow_num"])),
                    'used_num' => Db::raw('used_num - ' . intval($borrowRecord["borrow_num"])),
                    'model_status' => $model_status
                ]);
                
            if ($updateResult === false) {
                Db::rollback();
                Log::record('[Flow][cancelBorrowList] update main engine fail, fixed_no: ' . $borrowRecord['fixed_no']);
                return apiResponse(ERROR, '更新设备库存失败');
            }
            
            // 删除借用记录
            $deleteResult = Db::table("ems_my_borrow")
                ->where("ems_request_id", $ems_request_id)
                ->delete();
                
            if ($deleteResult === false) {
                Db::rollback();
                Log::record('[Flow][cancelBorrowList] delete borrow record fail, ems_request_id: ' . $ems_request_id);
                return apiResponse(ERROR, '删除借用记录失败');
            }
            
            // 提交事务
            Db::commit();
            
            Log::record('[Flow][cancelBorrowList] success, ems_request_id: ' . $ems_request_id . ', fixed_no: ' . $borrowRecord['fixed_no']);

            return apiResponse(SUCCESS, '[Flow][cancelBorrowList] success', [
                'fixed_no' => $borrowRecord['fixed_no'],
                'borrow_num' => $borrowRecord['borrow_num']
            ]);
            
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            
            // 记录错误日志
            Log::record('[Flow][cancelBorrowList] error: ' . $e->getMessage());
            
            return apiResponse(ERROR, 'server error');
        }
    }

    /**
     * showdoc
     * @catalog 接口文档/流程相关/申请
     * @title 样品借出
     * @description 样品借出
     * @method get
     * @param fixed_nos 必选 string fixed_nos=[]
     * @param apply_num 必选 int 申请数量
     * @return {"status":0,"msg":"[Flow][borrowApply] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/borrowApply
     * @remark 1.样品申请人->课长; 2.返回状态1代表失败
     */
    public function borrowApply() {
        // 开启数据库事务
        Db::startTrans();
        
        try {
            $userId = $this->loginUser['ems'];
            $userInfo = $this->getUserInfoById($userId);

            // 给subject用
            $user = $userInfo['USER_NAME'];
            $from = $userInfo['MAIL'];
            $sectionArray = getSections();

            // 参数验证和处理
            $fixed_nos_param = $this->request->param('fixed_nos');
            if (empty($fixed_nos_param)) {
                Db::rollback();
                return apiResponse(ERROR, '固定资产编号不能为空');
            }
            
            $fixed_nos = json_decode($fixed_nos_param, true);
            
            if (!is_array($fixed_nos) || empty($fixed_nos)) {
                Db::rollback();
                return apiResponse(ERROR, '固定资产编号格式错误');
            }
            
            $apply_num = intval($this->request->param('apply_num'));
            if ($apply_num <= 0) {
                Db::rollback();
                return apiResponse(ERROR, '申请数量必须大于0');
            }
            

            $predictDate = date('Y-m-d H:i:s', strtotime('+1 month')); // 预计归还时间：当前时间加一个月
            
            // 需要插入的数据
            $inputData = array();
            $processedItems = array(); // 记录已处理的项目，用于回滚

            // 逐个处理每个固定资产，使用行级锁防止并发问题
            foreach ($fixed_nos as $fixed_no) {
                if (empty($fixed_no)) {
                    continue;
                }
                
                // 使用 FOR UPDATE 锁定行，防止并发修改
                $query = Db::table('ems_main_engine')
                    ->where('fixed_no', $fixed_no)
                    ->whereIn('model_status', [IN_STORE,PART_USING])
                    ->where('inventory_num', '>=', $apply_num)
                    ->find();
                    
                if (empty($query)) {
                    Db::rollback();
                    return apiResponse(ERROR, "设备 {$fixed_no} 库存不足或状态不可用");
                }
                
                // 原子性更新库存和状态
                $res = Db::table('ems_main_engine')
                    ->where('fixed_no', $fixed_no)
                    ->whereIn('model_status', [IN_STORE,PART_USING])
                    ->where('inventory_num', '>=', $apply_num) // 再次检查库存
                    ->update(array(
                        'user_name'    => $user,
                        'user_id'      => $userId,
                        'model_status' => BORROW_REVIEW,
                        'predict_date' => $predictDate,
                        'inventory_num' => Db::raw('inventory_num - ' . $apply_num),
                        'used_num' => Db::raw('used_num + ' . $apply_num),
                    ));

                // 检查更新是否成功
                if ($res !== 1) {
                    Db::rollback();
                    Log::record('[Flow][borrowApply] update fail for ' . $fixed_no . ', affected rows: ' . $res);
                    return apiResponse(ERROR, "设备 {$fixed_no} 更新失败，可能库存不足");
                }
                
                // 记录已处理的项目
                $processedItems[] = $fixed_no;
                
                // 准备邮件数据
                $tmp = array(
                    'id' => $query['fixed_no'],
                    'name' => $query['MODEL_NAME'],
                    'category' => $query['category'],
                    'big_category' => $query['big_category'],
                    'number' => $apply_num,
                    'predictDate' => $predictDate,
                    'desc' => isset($query['remark']) ? $query['remark'] : ''
                );
                
                $section_manager = isset($query['section_manager']) ? $query['section_manager'] : 'default';
                if (!isset($inputData[$section_manager])) {
                    $inputData[$section_manager] = array();
                }
                $inputData[$section_manager][] = $tmp;

                // 插入日志记录
                $logData = array(
                    'id' => null,
                    'fixed_no' => $query['fixed_no'],
                    'desc' => LOG_DESC_BORROW,
                    'role' => isset($this->loginUser['desc']) ? $this->loginUser['desc'] : '',
                    'operator' => $user,
                    'type' => LOG_TYPE_APPLY,
                    'result' => LOG_RESULT_ADD,
                    'time' => Db::raw('now()')
                );
                
                $logResult = $this->insertLogRecordForBorrowApply($logData);
                if (!$logResult) {
                    Db::rollback();
                    Log::record('[Flow][borrowApply] log insert fail for ' . $fixed_no);
                    return apiResponse(ERROR, "设备 {$fixed_no} 日志记录失败");
                }
                
                $ems_request_id=$this->getRequestIdString();
                 Log::record('[Flow][borrowApply] ems_request_id ' . $ems_request_id);
                // 插入借用记录
                $borrowData = array(
                    'ems_request_id' => $ems_request_id,
                    'fixed_no' => $query['fixed_no'],
                    'user_name' => $user,
                    'borrow_num' => $apply_num,
                    'borrow_time' => Db::raw('now()'),
                    'insert_time' => Db::raw('now()'),
                    'update_time' => Db::raw('now()'),
                    'user_id' => $userId,
                    'request_status'=>BORROW_REVIEW,
                    'is_delete'=>0
                );
                
                $borrowResult = Db::table('ems_my_borrow')->insert($borrowData);
                
                if (!$borrowResult) {
                    Db::rollback();
                    Log::record('[Flow][borrowApply] borrow record insert fail for ' . $fixed_no);
                    return apiResponse(ERROR, "设备 {$fixed_no} 借用记录插入失败");
                }
            }

            // 检查是否有成功处理的项目
            if (empty($processedItems)) {
                Db::rollback();
                return apiResponse(ERROR, '没有可处理的设备');
            }

            // 存入邮件队列表中
            if (!empty($inputData)) {
                foreach ($inputData as $sec => $value) {
                    $to = $this->getSectionAddress($sec);
                    $section = isset($sectionArray[$userInfo['SECTION']]) ? $sectionArray[$userInfo['SECTION']] : '';
                    $subject = config('mail_header_subject') . MailTemplate::$subjectBorrowApply . $section . ' ' . $user;
                    $mainBody = MailTemplate::getBorrowApply($section, $user);

                    // 插入邮件队列数据
                    $mailData = array(
                        'id' => null, 
                        'type' => APPLY, 
                        'main_body' => $mainBody, 
                        'subject' => $subject,
                        'from' => $from, 
                        'to' => json_encode($to), 
                        'table_data' => json_encode($value)
                    );
                    
                    $mailResult = Db::table('ems_mail_queue')->insert($mailData);
                    if (!$mailResult) {
                        Db::rollback();
                        Log::record('[Flow][borrowApply] mail queue insert fail for section ' . $sec);
                        return apiResponse(ERROR, '邮件队列插入失败');
                    }
                }
            }
            
            // 提交事务
            Db::commit();
            
            Log::record('[Flow][borrowApply] success for user ' . $userId . ', processed items: ' . implode(',', $processedItems));
            return apiResponse(SUCCESS, '[Flow][borrowApply] success');
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][borrowApply] error: ' . $e->getMessage() . ', trace: ' . $e->getTraceAsString());
            return apiResponse(ERROR, 'server error');
        }
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关/审批
     * @title 样品借出(课长)
     * @description 样品借出(课长)
     * @method get
     * @param ems_request_id 必选 string ems_request_id=[]
     * @param judge 必选 string agree/disagree
     * @param reason 必选 string
     * @return {"status":0,"msg":"[Flow][replyBorrowApplyFromSection] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/replyBorrowApplyFromSection
     * @remark 1.课长->同意/拒绝; 2.返回状态1代表失败
     */
    public function replyBorrowApplyFromSection() {
        try {
            $userId = $this->loginUser['ems'];
            $judge = $this->request->param('judge');
            $ems_request_id_param = $this->request->param('ems_request_id');
            

            // JSON 参数验证
            $ems_request_id = json_decode($ems_request_id_param,true);
            $user = $this->getUserInfoById($userId);
            if (empty($user)) {
                return apiResponse(ERROR, 'User not found');
            }
            
            $inputData = array();
            
            // 开启数据库事务
            Db::startTrans();
            
            if ('agree' == $judge) {
                $inputData = $this->handleApprovalProcess($ems_request_id, $userId, $user);
            } else {
                $reason = $this->request->param('reason');
                if (empty($reason)) {
                    Db::rollback();
                    return apiResponse(ERROR, 'Reject reason is required');
                }
                $inputData = $this->handleRejectionProcess($ems_request_id, $reason, $user);
            }
            
            // 处理邮件发送
            if (!empty($inputData)) {
                $mailResult = $this->sendNotificationMails($inputData, $judge, $user);
                if (!$mailResult) {
                    Db::rollback();
                    return apiResponse(ERROR, 'Failed to send notification emails');
                }
            }
            
            // 提交事务
            Db::commit();
            return apiResponse(SUCCESS, '[Flow][replyBorrowApplyFromSection] success');
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][replyBorrowApplyFromSection] error: ' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }
    }

    /**
     * 处理同意审批流程
     */
    private function handleApprovalProcess($ems_request_id, $userId, $user) {
        $inputData = array();
        
        for ($i = 0; $i < count($ems_request_id); $i++) {
            $borrowData = $this->getBorrowRequestData($ems_request_id[$i]);
            
            if (empty($borrowData)) {
                Log::record('[Flow][handleApprovalProcess] no data for request: ' . $ems_request_id[$i]);
                continue;
            }
            
            // 使用行级锁防止并发问题
            $updateResult = Db::table('ems_main_engine')
                ->where('fixed_no', $borrowData['fixed_no'])
                ->where('model_status', BORROW_REVIEW)
                ->whereNotNull('user_id')
                ->update(array(
                    'approver_id'   => $userId,
                    'start_date'    => Db::raw('now()'),
                    'approve_date'  => Db::raw('now()'),
                    'approver_name' => $user['USER_NAME'],
                    'model_status'  => ASSIGNING
                ));
                
            if (1 !== $updateResult) {
                throw new Exception('Failed to update ems_main_engine for request: ' . $ems_request_id[$i]);
            }
            
            // 更新借用记录状态
            $borrowUpdateResult = Db::table('ems_my_borrow')
                ->where('ems_request_id', $ems_request_id[$i])
                ->update(['request_status' => ASSIGNING]);
                
            if (1 !== $borrowUpdateResult) {
                throw new Exception('Failed to update ems_my_borrow for request: ' . $ems_request_id[$i]);
            }
            
            // 准备邮件数据
            $predictDate = empty($borrowData['predict_date']) ? ' - ' : date("Y-m-d", strtotime($borrowData['predict_date']));
            $tmp = array(
                'id' => $borrowData['fixed_no'],
                'name' => $borrowData['MODEL_NAME'],
                'predictDate' => $predictDate,
                'desc' => $borrowData['remark'],
                'category'=>$borrowData['category'],
                'big_category'=>$borrowData['big_category'],
                'number'=>$borrowData['borrow_num']
            );
            $inputData[] = $tmp;
            
            // 记录日志
            $this->insertLogRecord(array(
                'id' => null,
                'fixed_no' => $borrowData['fixed_no'],
                'desc' => LOG_DESC_BORROW,
                'role' => $this->loginUser['desc'],
                'operator' => $user['USER_NAME'],
                'type' => LOG_TYPE_CHECK,
                'result' => LOG_RESULT_APPROVE,
                'time' => Db::raw('now()')
            ));
        }
        
        return $inputData;
    }

    /**
     * 处理拒绝审批流程
     */
    private function handleRejectionProcess($ems_request_id, $reason, $user) {
        $inputData = array();
        
        for ($i = 0; $i < count($ems_request_id); $i++) {
            $borrowData = $this->getBorrowRequestData($ems_request_id[$i],BORROW_REVIEW);
            
            if (empty($borrowData)) {
                Log::record('[Flow][handleRejectionProcess] no data for request: ' . $ems_request_id[$i]);
                continue;
            }
            $remain_num=$borrowData["used_num"]-$borrowData["borrow_num"];
            if($remain_num<0){
                Db::rollback();
                Log::record('[Flow][cancelBorrowList] remain_num: ' . $remain_num);
                return apiResponse(ERROR, '使用数比借用数小');
            }elseif ($remain_num ==0){
                $model_status=IN_STORE;
            }elseif($remain_num>0){
                $model_status=PART_USING;
            }
            // 使用行级锁更新设备状态
            $updateResult = Db::table('ems_main_engine')
                ->where('fixed_no', $borrowData['fixed_no'])
                ->where('model_status', BORROW_REVIEW)
                ->update(array(
                    'user_name'     => null,
                    'user_id'       => null,
                    'model_status'  => $model_status,
                    'predict_date'  => null,
                    'inventory_num' => Db::raw('inventory_num + ' . $borrowData['borrow_num']),
                    'used_num'      => Db::raw('used_num - ' . $borrowData['borrow_num'])
                ));
                
            if (1 !== $updateResult) {
                throw new Exception('Failed to update ems_main_engine for request: ' . $ems_request_id[$i]);
            }
            
            // 删除借用记录
            $deleteResult = Db::table('ems_my_borrow')
                ->where('ems_request_id', $ems_request_id[$i])
                ->update(['is_delete' => 1]);
                
            if (!$deleteResult) {
                throw new Exception('Failed to delete ems_my_borrow for request: ' . $ems_request_id[$i]);
            }
            
            // 准备邮件数据（按用户分组）
            $tmp = array(
                'id' => $borrowData['fixed_no'],
                'name' => $borrowData['MODEL_NAME'],
                'desc' => $borrowData['remark'],
                'rejectReason' => $reason,
                'category'=>$borrowData['category'],
                'big_category'=>$borrowData['big_category'],
                'number'=>$borrowData['borrow_num']
            );
            
            if (!isset($inputData[$borrowData['user_id']])) {
                $inputData[$borrowData['user_id']] = array();
            }
            $inputData[$borrowData['user_id']][] = $tmp;
            
            // 记录日志
            $this->insertLogRecord(array(
                'id' => null,
                'fixed_no' => $borrowData['fixed_no'],
                'desc' => LOG_DESC_BORROW,
                'role' => $this->loginUser['desc'],
                'operator' => $user['USER_NAME'],
                'type' => LOG_TYPE_CHECK,
                'result' => LOG_RESULT_REJECT,
                'reason' => $reason,
                'time' => Db::raw('now()')
            ));
            
            // 更新拒绝标记
            $this->updateRejectFlag($borrowData['fixed_no']);
        }
        
        return $inputData;
    }

    /**
     * 获取借用请求数据
     * @param $ems_request_id
     * @param null|int|array $status 状态值，可以是单个值或数组
     * @return array|false|\PDOStatement|string|\think\Model
     */
    private function getBorrowRequestData($ems_request_id, $status = null) {
        $query = Db::table('ems_my_borrow emb')
            ->field("e.*,emb.ems_request_id,emb.borrow_num")
            ->join("ems_main_engine e", "e.fixed_no = emb.fixed_no", "LEFT")
            ->where('emb.ems_request_id', $ems_request_id)
            ->where('emb.is_delete', 0);
            
        if ($status !== null) {
            if (is_array($status)) {
                // 如果status是数组，使用whereIn
                $query->whereIn('emb.request_status', $status);
            } else {
                // 如果status是单个值，使用where
                $query->where('emb.request_status', $status);
            }
        }
        
        return $query->find();
    }

    /**
     * 发送通知邮件
     */
    private function sendNotificationMails($inputData, $judge, $user) {
        if ('agree' == $judge) {
            // 同意邮件
            $to = $this->getSampleAddress(EMS_ADMIN);
            $subject = config('mail_header_subject') . MailTemplate::$subjectBorrowApplyApproveFromSection . $user['USER_NAME'];
            $mainBody = MailTemplate::getReplyApproveBorrowApplyFromSection();
            
            $data = array(
                'id' => null,
                'type' => APPLY,
                'main_body' => $mainBody,
                'subject' => $subject,
                'from' => $user['MAIL'],
                'to' => json_encode($to),
                'table_data' => json_encode($inputData)
            );
            
            $result = Db::table('ems_mail_queue')->insert($data);
            return 1 === $result;
            
        } else {
            // 拒绝邮件（按用户发送）
            foreach ($inputData as $userId => $userRequests) {
                $to = $this->getUserInfoById($userId);
                if (empty($to)) {
                    Log::record('[Flow][sendNotificationMails] User not found: ' . $userId);
                    continue;
                }
                
                $subject = config('mail_header_subject') . MailTemplate::$subjectBorrowApplyRejectFromSection . $user['USER_NAME'];
                $mainBody = MailTemplate::getReplyRejectBorrowApplyFromSection($to['USER_NAME']);
                
                $data = array(
                    'id' => null,
                    'type' => REJECT,
                    'main_body' => $mainBody,
                    'subject' => $subject,
                    'from' => $user['MAIL'],
                    'to' => json_encode(array($to['MAIL'])),
                    'table_data' => json_encode($userRequests)
                );
                
                $result = Db::table('ems_mail_queue')->insert($data);
                if (1 !== $result) {
                    return false;
                }
            }
            return true;
        }
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关
     * @title 样品分配
     * @description 样品分配
     * @method get
     * @param fixed_nos 必选 string fixed_nos=[]
     * @param judge 必选 string agree/disagree
     * @param reason 必选 string
     * @return {"status":0,"msg":"[Flow][replyBorrowApplyFromSample] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/replyBorrowApplyFromSample
     * @remark 1.样品管理员->同意/拒绝; 2.返回状态1代表失败
     */
    public function replyBorrowApplyFromSample() {
        try {
            $userId = $this->loginUser['ems'];
            $judge = $this->request->param('judge');
            $ems_request_id = json_decode($this->request->param('ems_request_id'));
            
            // 参数验证
            if (empty($ems_request_id) || !is_array($ems_request_id)) {
                return apiResponse(ERROR, 'Invalid request parameters');
            }
            
            $user = $this->getUserInfoById($userId);
            if (empty($user)) {
                return apiResponse(ERROR, 'User not found');
            }
            
            $inputData = array();
            
            // 开启事务
            Db::startTrans();
            
            try {
                if ('agree' == $judge) {
                    // 同意分配
                    $inputData = $this->processApprovalRequests($ems_request_id, $user);
                } else {
                    // 拒绝申请
                    $reason = $this->request->param('reason');
                    if (empty($reason)) {
                        throw new Exception('Reject reason is required');
                    }
                    $inputData = $this->processRejectionRequests($ems_request_id, $user, $reason);
                }
                
                // 发送邮件通知
                if (!empty($inputData)) {
                    $this->sendNotificationEmails($inputData, $user, $judge);
                }
                
                // 提交事务
                Db::commit();
                return apiResponse(SUCCESS, '[Flow][replyBorrowApplyFromSample] success');
                
            } catch (Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
            
        } catch (Exception $e) {
            Log::record('[Flow][replyBorrowApplyFromSample] error: ' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }
    }

    /**
     * 处理同意申请
     */
    private function processApprovalRequests($ems_request_id, $user) {
        $inputData = array();
        
        for ($i = 0; $i < count($ems_request_id); $i++) {
            $borrowData = $this->getBorrowRequestData($ems_request_id[$i], ASSIGNING);
            if (empty($borrowData)) {
                Log::record('[Flow][replyBorrowApplyFromSample] no data for request: ' . $ems_request_id[$i]);
                continue;
            }
            $old_data=Db::table('ems_main_engine')
                ->field("total_num,used_num,category,big_category")
                ->where('fixed_no', $borrowData['fixed_no'])
                ->where('model_status', ASSIGNING)
                ->find();
            if($old_data['total_num']==$old_data["used_num"]){
                $model_status = USING;
            }elseif ($old_data['total_num']>$old_data["used_num"]) {
                $model_status = PART_USING;
            }
            
            // 更新设备状态 - 根据total_num和used_num动态设置model_status
            $res = Db::table('ems_main_engine')
                ->where('fixed_no', $borrowData['fixed_no'])
                ->where('model_status', ASSIGNING)
                ->update([
                    'model_status' => $model_status
                ]);
                
            if ($res != 1) {
                throw new Exception('Failed to update equipment status for: ' . $borrowData['fixed_no']);
            }
            
            // 更新借用记录状态
            $borrowRes = Db::table('ems_my_borrow')
                ->where('ems_request_id', $ems_request_id[$i])
                ->update(['request_status' => USING]);
                
            if ($borrowRes != 1) {
                throw new Exception('Failed to update borrow status for request: ' . $ems_request_id[$i]);
            }
            
            // 准备邮件数据
            $tmp = array();
            $tmp['id'] = $borrowData['fixed_no'];
            $tmp['name'] = $borrowData['MODEL_NAME'];
            $tmp['predictDate'] = empty($borrowData['predict_date']) ? ' - ' : 
                date("Y-m-d", strtotime($borrowData['predict_date']));
            $tmp['desc'] = $borrowData['remark'];
            $tmp['category'] = $borrowData['category'];
            $tmp['big_category'] = $borrowData['big_category'];
            $tmp['number'] = $borrowData["borrow_num"];


            $inputData[$borrowData['user_id']][] = $tmp;
            
            // 添加历史记录
            $historyData = array(
                'ID' => null,
                'FIXED_NO' => $borrowData['fixed_no'],
                'user_id' => $borrowData['user_id'],
                'user_name' => $borrowData['user_name'],
                'start_date' => $borrowData['start_date'],
                'predict_date' => $borrowData['predict_date'],
                'remark' => $borrowData['remark'],
                'approver_id' => $borrowData['approver_id'],
                'approver_name' => $borrowData['approver_name'],
                'approve_date' => $borrowData['approve_date'],
                'assign_operator_name' => $user['USER_NAME'],
                'assign_operator_ID' => $user['USER_ID'],
                'borrow_num' => $borrowData['borrow_num'],
                'return_num' => 0,
                'ems_request_id'=> $ems_request_id[$i]
            );
            $historyRes = Db::table('ems_borrow_history')->insert($historyData);
            if ($historyRes != 1) {
                throw new Exception('Failed to insert history record for: ' . $ems_request_id[$i]);
            }
            
            // 插入日志记录
            $this->insertLogRecord(array(
                'id' => null,
                'fixed_no' => $borrowData['fixed_no'],
                'desc' => LOG_DESC_ASSIGN,
                'role' => $this->loginUser['desc'],
                'operator' => $user['USER_NAME'],
                'type' => LOG_TYPE_CHECK,
                'result' => LOG_RESULT_APPROVE,
                'time' => Db::raw('now()')
            ));
        }
        
        return $inputData;
    }

    /**
     * 处理拒绝申请
     */
    private function processRejectionRequests($ems_request_id, $user, $reason) {
        $inputData = array();
        
        for ($i = 0; $i < count($ems_request_id); $i++) {
            $borrowData = $this->getBorrowRequestData($ems_request_id[$i], ASSIGNING);
            if (empty($borrowData)) {
                Log::record('[Flow][replyBorrowApplyFromSample] no data for request: ' . $ems_request_id[$i]);
                continue;
            }
            $old_data = Db::table('ems_main_engine')
                ->field("used_num,category,big_category")
                ->where('fixed_no', $borrowData['fixed_no'])
                ->where('model_status', ASSIGNING)
                ->find();
            $remain_num=$old_data["used_num"]-$borrowData["borrow_num"];
            if($remain_num<0){
                Db::rollback();
                Log::record('[Flow][replyBorrowApplyFromSample]'.$borrowData['fixed_no'].$remain_num);
                return apiResponse(ERROR,"使用数比借用数小");
            }elseif($remain_num==0){
                $model_status=IN_STORE;
            }else{
                $model_status = PART_USING;
            }
            // 恢复设备状态和库存
            $res = Db::table('ems_main_engine')
                ->where('fixed_no', $borrowData['fixed_no'])
                ->where('model_status', ASSIGNING)
                ->update(array(
                    'user_name' => null,
                    'user_id' => null,
                    'approver_id' => null,
                    'start_date' => null,
                    'approve_date' => null,
                    'approver_name' => null,
                    'model_status' => $model_status,
                    'predict_date' => null,
                    'inventory_num' => Db::raw('inventory_num + ' . $borrowData['borrow_num']),
                    'used_num' => Db::raw('used_num - ' . $borrowData['borrow_num'])
                ));
                
            if ($res != 1) {
                throw new Exception('Failed to restore equipment status for: ' . $borrowData['fixed_no']);
            }
            
            // 标记借用记录为删除
            $borrowRes = Db::table('ems_my_borrow')
                ->where('ems_request_id', $ems_request_id[$i])
                ->update(array('is_delete' => 1));
                
            if ($borrowRes != 1) {
                throw new Exception('Failed to delete borrow record for request: ' . $ems_request_id[$i]);
            }
            
            // 准备邮件数据
            $tmp = array();
            $tmp['id'] = $borrowData['fixed_no'];
            $tmp['name'] = $borrowData['MODEL_NAME'];
            $tmp['rejectReason'] = $reason;
            $tmp['desc'] = $borrowData['remark'];
            $tmp['category'] = $borrowData['category'];
            $tmp['big_category'] = $borrowData['big_category'];
            $tmp['number'] = $borrowData["borrow_num"];

            $inputData[$borrowData['user_id']][] = $tmp;
            
            // 插入日志记录
            $this->insertLogRecord(array(
                'id' => null,
                'fixed_no' => $borrowData['fixed_no'],
                'desc' => LOG_DESC_ASSIGN,
                'role' => $this->loginUser['desc'],
                'operator' => $user['USER_NAME'],
                'type' => LOG_TYPE_CHECK,
                'result' => LOG_RESULT_REJECT,
                'reason' => $reason,
                'time' => Db::raw('now()')
            ));
            
            $this->updateRejectFlag($borrowData['fixed_no']);
        }
        
        return $inputData;
    }

    /**
     * 发送邮件通知
     */
    private function sendNotificationEmails($inputData, $user, $judge) {
        foreach ($inputData as $userId => $items) {
            $to = $this->getUserInfoById($userId);
            if (empty($to)) {
                Log::record('[Flow][replyBorrowApplyFromSample] User not found for notification: ' . $userId);
                continue;
            }
            
            if ('agree' == $judge) {
                $subject = config('mail_header_subject') . MailTemplate::$subjectBorrowApplyApproveFromSample . $user['USER_NAME'];
                $mainBody = MailTemplate::getReplyApproveBorrowApplyFromSample($to['USER_NAME']);
                $type = APPLY;
            } else {
                $subject = config('mail_header_subject') . MailTemplate::$subjectBorrowApplyRejectFromSample . $user['USER_NAME'];
                $mainBody = MailTemplate::getReplyRejectBorrowApplyFromSample($to['USER_NAME']);
                $type = REJECT;
            }
            
            $mailData = array(
                'id' => null,
                'type' => $type,
                'main_body' => $mainBody,
                'subject' => $subject,
                'from' => $user['MAIL'],
                'to' => json_encode(array($to['MAIL'])),
                'table_data' => json_encode($items)
            );
            
            $mailRes = Db::table('ems_mail_queue')->insert($mailData);
            if ($mailRes != 1) {
                throw new Exception('Failed to insert mail queue for user: ' . $userId);
            }
        }
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关
     * @title 样品归还
     * @description 样品归还
     * @method get
     * @param fixed_nos 必选 string fixed_nos=[]
     * @return {"status":0,"msg":"[Flow][returnSample] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/returnSample
     * @remark 1.样品管理员->归还; 2.返回状态1代表失败
     */
    public function returnSample() {
        // 开启事务
        Db::startTrans();
        try {
            $userId = $this->loginUser['ems'];

            $ems_request_id = json_decode($this->request->param('ems_request_id'),true);
            $apply_num = $this->request->param('apply_num'); 
            $user = $this->getUserInfoById($userId);
            
            // 参数验证
            if (empty($ems_request_id) || !is_array($ems_request_id)) {
                Db::rollback();
                return apiResponse(ERROR, '固定资产编号参数无效');
            }
            
            if (!is_numeric($apply_num) || $apply_num <= 0) {
                Db::rollback();
                return apiResponse(ERROR, '归还数量参数无效');
            }

            // 比较归还数量是否满足已使用数量
            $availableCount = Db::table('ems_my_borrow')
                ->whereIn('ems_request_id', $ems_request_id)
                ->whereIn('request_status', [USING,PART_USING])
                ->where('borrow_num','>=', $apply_num)
                ->count();
            if ($availableCount < count($ems_request_id)) {
                Db::rollback();
                return apiResponse(ERROR, '归还数量大于已使用数量');
            }
            $inputData = array();

            for ($i = 0; $i < count($ems_request_id); $i++) {
                $query = $this->getBorrowRequestData($ems_request_id[$i],  [USING,PART_USING]);
//                $query = Db::table('ems_main_engine')->where('fixed_no', $ems_request_id[$i])
//                    ->where('model_status', USING)->find();

                if (!empty($query)) {
                    // 计算归还后的剩余使用数量
                    $remaining_used = $query['used_num'] - $apply_num;
                    
                    // 根据剩余使用数量决定状态
                    $new_status = ($remaining_used == 0) ? IN_STORE : PART_USING;
                    
                    $res = Db::table('ems_main_engine')->where('fixed_no', $query['fixed_no'])
                        ->whereIn('model_status', [USING,PART_USING])
                        ->update([
                            'user_name'    => null,
                            'user_id'      => null,
                            'approver_id'    => null,
                            'start_date'    => null,
                            'approve_date'  => null,
                            'approver_name'  => null,
                            'predict_date'  => null,
                            'model_status' => $new_status,
                            'inventory_num' => Db::raw('inventory_num + ' . $apply_num),
                            'used_num' => Db::raw('used_num - ' . $apply_num)
                        ]);

                    if (1 == $res) {
                        $tmp['id'] = $query['fixed_no'];
                        $tmp['name'] = $query['MODEL_NAME'];
                        $tmp['desc'] = $query['remark'];
                        $tmp['category'] = $query['category'];
                        $tmp['big_category'] = $query['big_category'];
                        $tmp['number'] = $apply_num;
                        $inputData[$query['user_id']][] = $tmp;

                        // 更新记录到history中
                        $data = [
                            'end_date' => Db::raw('now()'), // 使用结束时间
                            'confirm_operator_id'=>$user['USER_ID'],
                            'confirm_operator_name'=>$user['USER_NAME'],
                            'return_num'=>Db::raw('return_num +' . $apply_num)
                        ];

                        $r = Db::table('ems_borrow_history')->where('ems_request_id', $ems_request_id[$i])
                                   ->update($data);
                        if (1 != $r) {
                            Log::record('[Flow][returnSample] update history fail ' . $ems_request_id[$i]);
                            Db::rollback();
                            return apiResponse(ERROR, '更新借用历史记录失败');
                        }
                        $return_old_data=Db::table('ems_my_borrow')
                            ->field("borrow_num")
                            ->where('ems_request_id', $ems_request_id[$i])
                            ->find();
                        if(empty($return_old_data)){
                            Db::rollback();
                            return apiResponse(ERROR, '[Flow][returnSample] 找不到借出记录');
                        }
                        if($return_old_data["borrow_num"] - $apply_num<0){
                            Db::rollback();
                            return apiResponse(ERROR, '[Flow][returnSample] 归还数量大于申请数量'.$ems_request_id[$i].$apply_num);
                        }elseif ($return_old_data["borrow_num"] - $apply_num==0){
                            $is_delete=1;
                            $request_status=IN_STORE;
                        }else{
                            $is_delete=0;
                            $request_status=PART_USING;
                        }
                         Db::table('ems_my_borrow')
                            ->where('ems_request_id', $ems_request_id[$i])
                            ->update([
                                'borrow_num' => Db::raw('borrow_num - ' . $apply_num),
                                'is_delete' => $is_delete,
                                'request_status' => $request_status
                            ]);

                        $this->insertLogRecord([
                            'id'=>null,
                            'fixed_no'=>$query['fixed_no'],
                            'desc'=>LOG_DESC_RETURN,
                            'role'=>$this->loginUser['desc'],
                            'operator'=>$user['USER_NAME'],
                            'type'=>'-',
                            'result'=>'-',
                            'time'=>Db::raw('now()')
                        ]);
                    } else {
                        Log::record('[Flow][returnSample] update fail ' . $ems_request_id[$i]);
                        Db::rollback();
                        return apiResponse(ERROR, '更新主引擎表失败');
                    }
                } else {
                    Log::record('[Flow][returnSample] no data ' . $ems_request_id[$i]);
                    Db::rollback();
                    return apiResponse(ERROR, '未找到对应的设备记录，固定资产编号：' . $ems_request_id[$i]);
                }
            }

            if (!empty($inputData)) {
                foreach ($inputData as $key => $value) {
                    $to = $this->getUserInfoById($key);
                    $subject = config('mail_header_subject'). MailTemplate::$subjectReturnSample.$user['USER_NAME'];
                    $mainBody = MailTemplate::getReturnSample($to['USER_NAME']);

                    // 插入数据
                    $data = ['id'=>null, 'type'=>FLOW, 'main_body'=>$mainBody, 'subject'=>$subject,
                        'from'=>$user['MAIL'], 'to'=>json_encode(array($to['MAIL'])), // 定时任务判断是数组
                        'table_data' => json_encode($value)];

                    $mailResult = Db::table('ems_mail_queue')->insert($data);
                    if (!$mailResult) {
                        Log::record('[Flow][returnSample] insert mail queue fail');
                        Db::rollback();
                        return apiResponse(ERROR, '插入邮件队列失败');
                    }
                }
            }
            
            // 提交事务
            Db::commit();
            Log::record('[Flow][returnSample] success');
            return apiResponse(SUCCESS, '[Flow][returnSample] success');

        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][returnSample] error: ' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关/申请
     * @title 样品删除
     * @description 样品删除
     * @method get
     * @param fixed_nos 必选 string fixed_nos=[]
     * @return {"status":0,"msg":"[Flow][deleteApply] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/deleteApply
     * @remark 1.样品管理员(删除申请)->课长; 2.返回状态1代表失败
     */
    public function deleteApply() {
        try {
            $userId = $this->loginUser['ems'];

            $userInfo = $this->getUserInfoById($userId);

            // 给subject用
            $user = $userInfo['USER_NAME'];
            $from = $userInfo['MAIL'];
            $sectionArray = getSections();

            // 前端需要把数组变成字符串
            $fixed_nos = json_decode($this->request->param('fixed_nos'));// 转为数组

            // 需要插入的数据
            $inputData = array();

            for ($i = 0; $i < count($fixed_nos); $i++) {

                $query = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                    ->where('model_status', IN_STORE)->where('user_id', null)->find();
                if (!empty($query)) {
                    // 更新状态
                    $res = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                        ->where('model_status', IN_STORE)->where('user_id', null)
                        ->update([
                            'model_status'    => DELETE_REVIEW,
                            'scrap_operator'      => $user, // 老系统存入的就为用户名
                            'scrap_date' => Db::raw('now()'),
                        ]);

                    // 更新成功
                    if (1 == $res) {
                        $tmp['id'] = $query['fixed_no'];
                        $tmp['name'] = $query['MODEL_NAME'];
                        $tmp['desc'] = $query['remark'];
                        $tmp['category'] = $query['category'];
                        $tmp['big_category'] = $query['big_category'];

                        $inputData[$query['section_manager']][] = $tmp;

                        $this->insertLogRecord([
                            'id'=>null,
                            'fixed_no'=>$query['fixed_no'],
                            'desc'=>LOG_DESC_DELETE,
                            'role'=>$this->loginUser['desc'],
                            'operator'=>$user,
                            'type'=>LOG_TYPE_APPLY,
                            'result'=>LOG_RESULT_ADD,
                            'time'=>Db::raw('now()')
                        ]);
                    } else {
                        Log::record('[Flow][deleteApply] update fail ' . $fixed_nos[$i]);
                    }

                }
            }

            // 存入邮件队列表中
            if (!empty($inputData)) {
                foreach ($inputData as $sec => $value) {
                    $to = $this->getSectionAddress($sec);
                    $section = $sectionArray[$userInfo['SECTION']];
                    $subject = config('mail_header_subject'). MailTemplate::$subjectDeleteApply. $section. ' '.$user;
                    $mainBody = MailTemplate::getDeleteApply($section, $user);

                    // 插入数据
                    $data = ['id'=>null, 'type'=>FLOW, 'main_body'=>$mainBody, 'subject'=>$subject,
                        'from'=>$from, 'to'=>json_encode($to), 'table_data' => json_encode($value)];
                    Db::table('ems_mail_queue')->insert($data);
                }
                return apiResponse(SUCCESS, '[Flow][deleteApply] success');
            }

        } catch (Exception $e) {
            Log::record('[Flow][deleteApply] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');

        }
        return apiResponse(ERROR, 'server error');

    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关/审批
     * @title 样品删除(课长)
     * @description 样品删除(课长)
     * @method get
     * @param fixed_nos 必选 string fixed_nos=[]
     * @param judge 必选 string agree/disagree
     * @return {"status":0,"msg":"[Flow][replyDeleteApplyFromSection] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/replyDeleteApplyFromSection
     * @remark 1.课长->同意/拒绝; 2.返回状态1代表失败
     */
    // 老系统删除审批 【同意】 【不同意】 都不发送邮件
    public function replyDeleteApplyFromSection() {
        try {
            $userId = $this->loginUser['ems'];

            $judge = $this->request->param('judge');
            $fixed_nos = json_decode($this->request->param('fixed_nos'));

            $user = $this->getUserInfoById($userId);

            $inputData = array();
            if ('agree' == $judge) {
                // 课长同意， 则删除机器
                for ($i = 0; $i < count($fixed_nos); $i++) {
                    $query = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                        ->where('model_status', DELETE_REVIEW)->find();

                    if (!empty($query)) {
                        $res = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                            ->where('model_status', DELETE_REVIEW)
                            ->delete();
                        if (1 == $res) {
                            $tmp['id'] = $query['fixed_no'];
                            $tmp['name'] = $query['MODEL_NAME'];
                            $tmp['desc'] = $query['remark'];

                            $inputData[] = $tmp;

                            $this->insertLogRecord([
                                'id'=>null,
                                'fixed_no'=>$query['fixed_no'],
                                'desc'=>LOG_DESC_DELETE,
                                'role'=>$this->loginUser['desc'],
                                'operator'=>$user['USER_NAME'],
                                'type'=>LOG_TYPE_CHECK,
                                'result'=>LOG_RESULT_APPROVE,
                                'time'=>Db::raw('now()')
                            ]);
                        } else {
                            Log::record('[Flow][replyDeleteApplyFromSection] delete fail ' . $fixed_nos[$i]);
                        }
                    } else {
                        Log::record('[Flow][replyDeleteApplyFromSection] no data ' . $fixed_nos[$i]);
                    }
                }
                // 存入邮件队列表中
                if (!empty($inputData)) {
                    $to = $this->getSampleAddress(EMS_ADMIN);

                    $subject = config('mail_header_subject'). MailTemplate::$subjectDeleteApplyApproveFromSection.$user['USER_NAME'];
                    $mainBody = MailTemplate::getDeleteApproveFromSection();

                    // 插入数据
                    $data = ['id'=>null, 'type'=>FLOW, 'main_body'=>$mainBody, 'subject'=>$subject,
                        'from'=>$user['MAIL'], 'to'=>json_encode($to), 'table_data' => json_encode($inputData)];

                    $res = Db::table('ems_mail_queue')->insert($data);

                    if (1 == $res) {
                        return apiResponse(SUCCESS, '[Flow][replyDeleteApplyFromSection] success');
                    }
                    return apiResponse(ERROR, 'server error');
                }

            } else {
                // 更新状态到在库
                for ($i = 0; $i < count($fixed_nos); $i++) {
                    $query = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                        ->where('model_status', DELETE_REVIEW)->find();

                    if (!empty($query)) {
                        $res = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                            ->where('model_status', DELETE_REVIEW)
                            ->update([
                                'scrap_operator'      => null, // 老系统还会更新approve_id等根本没啥卵用
                                'scrap_date' => null,
                                'model_status'    => IN_STORE,
                            ]);

                        if (1 == $res) {
                            $tmp['id'] = $query['fixed_no'];
                            $tmp['name'] = $query['MODEL_NAME'];
                            $tmp['desc'] = $query['remark'];

                            $inputData[] = $tmp;

                            $this->insertLogRecord([
                                'id'=>null,
                                'fixed_no'=>$query['fixed_no'],
                                'desc'=>LOG_DESC_DELETE,
                                'role'=>$this->loginUser['desc'],
                                'operator'=>$user['USER_NAME'],
                                'type'=>LOG_TYPE_CHECK,
                                'result'=>LOG_RESULT_REJECT,
                                'time'=>Db::raw('now()')
                            ]);
                        } else {
                            Log::record('[Flow][replyDeleteApplyFromSection] update fail ' . $fixed_nos[$i]);
                        }
                    } else {
                        Log::record('[Flow][replyDeleteApplyFromSection] no data ' . $fixed_nos[$i]);
                    }
                }

                if (!empty($inputData)) {
                    $to = $this->getSampleAddress(EMS_ADMIN);

                    $subject = config('mail_header_subject'). MailTemplate::$subjectDeleteApplyRejectFromSection.$user['USER_NAME'];
                    $mainBody = MailTemplate::getDeleteRejectFromSection();

                    // 插入数据
                    $data = ['id'=>null, 'type'=>FLOW, 'main_body'=>$mainBody, 'subject'=>$subject,
                        'from'=>$user['MAIL'], 'to'=>json_encode($to), 'table_data' => json_encode($inputData)];

                    $res = Db::table('ems_mail_queue')->insert($data);

                    if (1 == $res) {
                        return apiResponse(SUCCESS, '[Flow][replyDeleteApplyFromSection] success');
                    }
                    return apiResponse(ERROR, 'server error');
                }
            }
        } catch (Exception $e) {
            Log::record('[Flow][replyDeleteApplyFromSection] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }
        return apiResponse(ERROR, 'server error');
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关/申请
     * @title 样品报废
     * @description 样品报废
     * @method get
     * @param fixed_nos 必选 string fixed_nos=[]
     * @return {"status":0,"msg":"[Flow][scrapApply] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/scrapApply
     * @remark 1.样品管理员(报废申请)->课长; 2.返回状态1代表失败
     */
    public function scrapApply() {
        // 开启数据库事务
        Db::startTrans();
        
        try {
            $userId = $this->loginUser['ems'];
            $userInfo = $this->getUserInfoById($userId);

            // 给subject用
            $user = $userInfo['USER_NAME'];
            $from = $userInfo['MAIL'];
            $sectionArray = getSections();

            // 前端需要把数组变成字符串
            $fixed_nos = json_decode($this->request->param('fixed_nos'));// 转为数组
            $scrap_num = intval($this->request->param('scrap_num'));

            // 参数验证
            if (empty($fixed_nos) || !is_array($fixed_nos)) {
                Db::rollback();
                return apiResponse(ERROR, '固定资产编号参数无效');
            }

            if ($scrap_num <= 0) {
                Db::rollback();
                return apiResponse(ERROR, '报废数量必须大于0');
            }

            // 需要插入的数据
            $inputData = array();
            $processedItems = array(); // 记录已处理的项目，用于回滚

            // 第一步：验证所有设备的库存是否足够
            for ($i = 0; $i < count($fixed_nos); $i++) {
                $query = Db::table('ems_main_engine')
                    ->where('fixed_no', $fixed_nos[$i])
                    ->whereIn('model_status', [IN_STORE,PART_USING,PART_SCRAPED])
                    ->find();
                    
                if (empty($query)) {
                    Db::rollback();
                    return apiResponse(ERROR, "设备 {$fixed_nos[$i]} 不存在或状态不可用");
                }

                // 检查库存是否足够
                if ($query['inventory_num'] < $scrap_num) {
                    Db::rollback();
                    return apiResponse(ERROR, "设备 {$fixed_nos[$i]} 库存数不足，当前库存：{$query['inventory_num']}，申请报废：{$scrap_num}");
                }
            }

            // 第二步：执行库存更新和状态变更
            for ($i = 0; $i < count($fixed_nos); $i++) {
                // 使用行级锁防止并发问题
                $query = Db::table('ems_main_engine')
                    ->where('fixed_no', $fixed_nos[$i])
                    ->whereIn('model_status', [IN_STORE,PART_USING,PART_SCRAPED])
                    ->where('inventory_num', '>=', $scrap_num) // 再次检查库存
                    ->lock(true)
                    ->find();
                    
                if (empty($query)) {
                    Db::rollback();
                    Log::record('[Flow][scrapApply] inventory check fail after lock for ' . $fixed_nos[$i]);
                    return apiResponse(ERROR, "设备 {$fixed_nos[$i]} 库存验证失败");
                }

                // 原子性更新库存、报废数和状态
                $res = Db::table('ems_main_engine')
                    ->where('fixed_no', $fixed_nos[$i])
                    ->whereIn('model_status', [IN_STORE,PART_USING,PART_SCRAPED])
                    ->where('inventory_num', '>=', $scrap_num) // 再次检查库存
                    ->update([
                        'model_status'    => SCRAP_REVIEW,
                        'scrap_operator'  => $user,
                        'scrap_date'      => Db::raw('now()'),
                        'inventory_num'   => Db::raw('inventory_num - ' . $scrap_num),
                        'scrap_num'       => Db::raw('scrap_num + ' . $scrap_num)
                    ]);
                // 检查更新是否成功
                if ($res !== 1) {
                    Db::rollback();
                    Log::record('[Flow][scrapApply] update fail for ' . $fixed_nos[$i] . ', affected rows: ' . $res);
                    return apiResponse(ERROR, "设备 {$fixed_nos[$i]} 更新失败，可能库存不足");
                }

                // 记录已处理的项目
                $processedItems[] = $fixed_nos[$i];

                // 准备邮件数据
                $tmp = array(
                    'id' => $query['fixed_no'],
                    'name' => $query['MODEL_NAME'],
                    'desc' => $query['remark']
                );
                $inputData[$query['section_manager']][] = $tmp;

                // 插入借用记录到ems_my_borrow表
                $borrowData = array(
                    'ems_request_id' => $this->getFIdString(),
                    'fixed_no' => $query['fixed_no'],
                    'user_name' => $user,
                    'borrow_num' => $scrap_num,
                    'borrow_time' => Db::raw('now()'),
                    'insert_time' => Db::raw('now()'),
                    'update_time' => Db::raw('now()'),
                    'user_id' => $userId,
                    'request_status' => SCRAP_REVIEW, // 使用报废审核状态
                    'is_delete' => 0
                );
                
                $borrowResult = Db::table('ems_my_borrow')->insert($borrowData);
                
                if (!$borrowResult) {
                    Db::rollback();
                    Log::record('[Flow][scrapApply] borrow record insert fail for ' . $fixed_nos[$i]);
                    return apiResponse(ERROR, "设备 {$fixed_nos[$i]} 借用记录插入失败");
                }

                // 插入日志记录
                $logResult = $this->insertLogRecordForBorrowApply([
                    'id'=>null,
                    'fixed_no'=>$query['fixed_no'],
                    'desc'=>LOG_DESC_SCRAPE,
                    'role'=>$this->loginUser['desc'],
                    'operator'=>$user,
                    'type'=>LOG_TYPE_APPLY,
                    'result'=>LOG_RESULT_ADD,
                    'time'=>Db::raw('now()')
                ]);

                if (!$logResult) {
                    Db::rollback();
                    Log::record('[Flow][scrapApply] log insert fail for ' . $fixed_nos[$i]);
                    return apiResponse(ERROR, "设备 {$fixed_nos[$i]} 日志记录失败");
                }
            }

            // 检查是否有成功处理的项目
            if (empty($processedItems)) {
                Db::rollback();
                return apiResponse(ERROR, '没有可处理的设备');
            }

            // 存入邮件队列表中
//            删除样品报废的邮件通知
//            if (!empty($inputData)) {
//                foreach ($inputData as $sec => $value) {
//                    $to = $this->getSectionAddress($sec);
//                    $section = isset($sectionArray[$userInfo['SECTION']]) ? $sectionArray[$userInfo['SECTION']] : '';
//                    $subject = config('mail_header_subject'). MailTemplate::$subjectScrapApply. $section. ' '.$user;
//                    $mainBody = MailTemplate::getScrapApply();
//
//                    // 插入邮件队列数据
//                    $mailData = ['id'=>null, 'type'=>FLOW, 'main_body'=>$mainBody, 'subject'=>$subject,
//                        'from'=>$from, 'to'=>json_encode($to), 'table_data' => json_encode($value)];
//
//                    $mailResult = Db::table('ems_mail_queue')->insert($mailData);
//                    if (!$mailResult) {
//                        Db::rollback();
//                        Log::record('[Flow][scrapApply] mail queue insert fail for section ' . $sec);
//                        return apiResponse(ERROR, '邮件队列插入失败');
//                    }
//                }
//            }

            // 提交事务
            Db::commit();
            
            Log::record('[Flow][scrapApply] success for user ' . $userId . ', processed items: ' . implode(',', $processedItems));
            return apiResponse(SUCCESS, '[Flow][scrapApply] success');

        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][scrapApply] error: ' . $e->getMessage() . ', trace: ' . $e->getTraceAsString());
            return apiResponse(ERROR, 'server error');
        }
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关/审批
     * @title 样品报废(课长)
     * @description 样品报废(课长)
     * @method get
     * @param ems_request_id 必选 string ems_request_id=[]
     * @param judge 必选 string agree/reject
     * @param reason 可选 string 拒绝原因(当judge为reject时必填)
     * @return {"status":0,"msg":"[Flow][replyScrapApplyFromSection] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/replyScrapApplyFromSection
     * @remark 1.课长->同意/拒绝; 2.返回状态1代表失败; 3.支持批量报废审批
     */
    public function replyScrapApplyFromSection() {
        // 开启数据库事务
        Db::startTrans();
        try {
            $userId = $this->loginUser['ems'];
            $judge = $this->request->param('judge');
            $ems_request_id_param = $this->request->param('ems_request_id');
            
            // 详细日志记录输入参数
            Log::record('[Flow][replyScrapApplyFromSection] start - userId: ' . $userId . ', judge: ' . $judge . ', ems_request_id_param: ' . $ems_request_id_param);
            
            // 参数验证
            if (empty($judge) || !in_array($judge, array('agree', 'disagree'))) {
                Db::rollback();
                Log::record('[Flow][replyScrapApplyFromSection] Invalid judge parameter: ' . $judge);
                return apiResponse(ERROR, 'Invalid judge parameter');
            }
            
            // JSON 参数验证
            $ems_request_id = json_decode($ems_request_id_param, true);
            if (empty($ems_request_id) || !is_array($ems_request_id)) {
                Db::rollback();
                Log::record('[Flow][replyScrapApplyFromSection] Invalid ems_request_id parameter: ' . $ems_request_id_param . ', json_last_error: ' . json_last_error());
                return apiResponse(ERROR, 'Invalid ems_request_id parameter');
            }
            
            Log::record('[Flow][replyScrapApplyFromSection] ems_request_id array: ' . json_encode($ems_request_id));

            $user = $this->getUserInfoById($userId);
            if (empty($user)) {
                Db::rollback();
                Log::record('[Flow][replyScrapApplyFromSection] User not found for userId: ' . $userId);
                return apiResponse(ERROR, 'User not found');
            }
            
            Log::record('[Flow][replyScrapApplyFromSection] User info: ' . json_encode($user));

            $inputData = array();
            Log::record('[Flow][replyScrapApplyFromSection] Processing judge: ' . $judge);
            
            if ('agree' == $judge) {
                // 课长同意
                Log::record('[Flow][replyScrapApplyFromSection] Processing agree logic, request count: ' . count($ems_request_id));
                for ($i = 0; $i < count($ems_request_id); $i++) {
                    Log::record('[Flow][replyScrapApplyFromSection] Processing request ' . ($i+1) . '/' . count($ems_request_id) . ': ' . $ems_request_id[$i]);
                    
                    $borrowData = $this->getBorrowRequestData($ems_request_id[$i], SCRAP_REVIEW);
                    
                    if (empty($borrowData)) {
                        Log::record('[Flow][replyScrapApplyFromSection] no data for request: ' . $ems_request_id[$i]);
                        continue;
                    }
                    
                    Log::record('[Flow][replyScrapApplyFromSection] Found borrowData: ' . json_encode($borrowData));
                    
                    // 计算更新后的数量，确定新状态
                    $totalNum = $borrowData['total_num'];
                    $usedNum = $borrowData['used_num'];
                    $currentScrapNum = $borrowData['scrap_num'];
                    
                    Log::record('[Flow][replyScrapApplyFromSection] Status calculation - totalNum: ' . $totalNum . ', usedNum: ' . $usedNum . ', currentScrapNum: ' . $currentScrapNum);
                    
                    // 确定新状态
                    $newStatus = $this->determineModelStatus($totalNum, $usedNum, $currentScrapNum);
                    
                    Log::record('[Flow][replyScrapApplyFromSection] Determined new status: ' . $newStatus . ' for fixed_no: ' . $borrowData['fixed_no']);
                    
                    // 更新设备状态
                    $res = Db::table('ems_main_engine')
                        ->where('fixed_no', $borrowData['fixed_no'])
                        ->where('model_status', SCRAP_REVIEW)
                        ->update([
                            'model_status'    => $newStatus,
                            'approver_id'     => $userId,
                            'approve_date'    => Db::raw('now()'),
                            'approver_name'   => $user['USER_NAME']
                        ]);
                        
                    Log::record('[Flow][replyScrapApplyFromSection] Main engine update result: ' . $res . ' for fixed_no: ' . $borrowData['fixed_no']);
                        
                    if (1 !== $res) {
                        Db::rollback();
                        Log::record('[Flow][replyScrapApplyFromSection] update fail for request: ' . $ems_request_id[$i] . ', affected rows: ' . $res);
                        return apiResponse(ERROR, 'Failed to update equipment status');
                    }
                    
                    // 更新借用记录状态为已报废
                    $borrowUpdateResult = Db::table('ems_my_borrow')
                        ->where('ems_request_id', $ems_request_id[$i])
                        ->update(['request_status' => SCRAPED]);
                        
                    if (1 !== $borrowUpdateResult) {
                        Db::rollback();
                        Log::record('[Flow][replyScrapApplyFromSection] update borrow record fail for request: ' . $ems_request_id[$i]);
                        return apiResponse(ERROR, 'Failed to update borrow record');
                    }
                    
                    // 准备邮件数据
                    $tmp = array(
                        'id' => $borrowData['fixed_no'],
                        'name' => $borrowData['MODEL_NAME'],
                        'desc' => $borrowData['remark']
                    );
                    $inputData[] = $tmp;

                    // 记录日志
                    $this->insertLogRecord([
                        'id' => null,
                        'fixed_no' => $borrowData['fixed_no'],
                        'desc' => LOG_DESC_SCRAPE,
                        'role' => $this->loginUser['desc'],
                        'operator' => $user['USER_NAME'],
                        'type' => LOG_TYPE_CHECK,
                        'result' => LOG_RESULT_APPROVE,
                        'time' => Db::raw('now()')
                    ]);
                }
                // 存入邮件队列表中
                // 发送同意邮件
                if (!empty($inputData)) {
                    $to = $this->getSampleAddress(EMS_ADMIN);
                    $subject = config('mail_header_subject'). MailTemplate::$subjectScrapApplyApproveFromSample.$user['USER_NAME'];
                    $mainBody = MailTemplate::getScrapApproveFromSample();

                    // 插入数据
                    $data = ['id'=>null, 'type'=>FLOW, 'main_body'=>$mainBody, 'subject'=>$subject,
                        'from'=>$user['MAIL'], 'to'=>json_encode($to), // 定时任务判断是数组
                        'table_data' => json_encode($inputData)];

                    $res = Db::table('ems_mail_queue')->insert($data);
                    if (!$res) {
                        Db::rollback();
                        return apiResponse(ERROR, 'Failed to insert approval mail queue');
                    }
                }

            } else {
                // 课长拒绝
                Log::record('[Flow][replyScrapApplyFromSection] Processing disagree logic, request count: ' . count($ems_request_id));
                $reason = $this->request->param('reason');
                Log::record('[Flow][replyScrapApplyFromSection] Reject reason: ' . $reason);
                if (empty($reason)) {
                    Db::rollback();
                    Log::record('[Flow][replyScrapApplyFromSection] Reject reason is empty');
                    return apiResponse(ERROR, '拒绝理由必填');
                }
                
                for ($i = 0; $i < count($ems_request_id); $i++) {
                    Log::record('[Flow][replyScrapApplyFromSection] Processing reject request ' . ($i+1) . '/' . count($ems_request_id) . ': ' . $ems_request_id[$i]);
                    
                    $borrowData = $this->getBorrowRequestData($ems_request_id[$i], SCRAP_REVIEW);
                    
                    if (empty($borrowData)) {
                        Log::record('[Flow][replyScrapApplyFromSection] no data for request: ' . $ems_request_id[$i]);
                        continue;
                    }
                    
                    Log::record('[Flow][replyScrapApplyFromSection] Found borrowData for reject: ' . json_encode($borrowData));
                    
                    // 计算恢复后的数量
                    $totalNum = $borrowData['total_num'];
                    $usedNum = $borrowData['used_num'];
                    $borrowNum = $borrowData['borrow_num']; // 从ems_my_borrow获取的报废申请数量
                    $newScrapNum = $borrowData['scrap_num'] - $borrowNum; // 恢复报废数量
                    
                    // 根据Java模板确定新状态
                    $newStatus = $this->determineModelStatus($totalNum, $usedNum, $newScrapNum);

                    // 恢复设备状态和数量
                    $res = Db::table('ems_main_engine')
                        ->where('fixed_no', $borrowData['fixed_no'])
                        ->where('model_status', SCRAP_REVIEW)
                        ->update([
                            'scrap_operator'  => null,
                            'scrap_date'      => null,
                            'approver_id'     => null,
                            'approve_date'    => null,
                            'approver_name'   => null,
                            'model_status'    => $newStatus,
                            'inventory_num'   => Db::raw('inventory_num + ' . $borrowNum),
                            'scrap_num'       => Db::raw('scrap_num - ' . $borrowNum)
                        ]);

                    if (1 !== $res) {
                        Db::rollback();
                        Log::record('[Flow][replyScrapApplyFromSection] update fail for request: ' . $ems_request_id[$i]);
                        return apiResponse(ERROR, 'Failed to restore equipment status');
                    }
                    
                    // 软删除借用记录
                    $borrowUpdateResult = Db::table('ems_my_borrow')
                        ->where('ems_request_id', $ems_request_id[$i])
                        ->update(['is_delete' => 1]);
                        
                    if (1 !== $borrowUpdateResult) {
                        Db::rollback();
                        Log::record('[Flow][replyScrapApplyFromSection] delete borrow record fail for request: ' . $ems_request_id[$i]);
                        return apiResponse(ERROR, 'Failed to delete borrow record');
                    }

                    // 准备邮件数据
                    $tmp = array(
                        'id' => $borrowData['fixed_no'],
                        'name' => $borrowData['MODEL_NAME'],
                        'desc' => $borrowData['remark'],
                        'rejectReason' => $reason
                    );
                    $inputData[] = $tmp;

                    // 记录日志
                    $this->insertLogRecord([
                        'id' => null,
                        'fixed_no' => $borrowData['fixed_no'],
                        'desc' => LOG_DESC_SCRAPE,
                        'role' => $this->loginUser['desc'],
                        'operator' => $user['USER_NAME'],
                        'type' => LOG_TYPE_CHECK,
                        'result' => LOG_RESULT_REJECT,
                        'reason' => $reason,
                        'time' => Db::raw('now()')
                    ]);
                    
                    // 更新拒绝标记
                    $this->updateRejectFlag($borrowData['fixed_no']);
                }

                // 发送拒绝邮件
                if (!empty($inputData)) {
                    $to = $this->getSampleAddress(EMS_ADMIN);
                    $subject = config('mail_header_subject'). MailTemplate::$subjectScrapApplyRejectFromSample.$user['USER_NAME'];
                    $mainBody = MailTemplate::getScrapRejectFromSample();

                    // 插入数据
                    $data = ['id'=>null, 'type'=>FLOW, 'main_body'=>$mainBody, 'subject'=>$subject,
                        'from'=>$user['MAIL'], 'to'=>json_encode($to), // 定时任务判断是数组
                        'table_data' => json_encode($inputData)];

                    $res = Db::table('ems_mail_queue')->insert($data);
                    if (!$res) {
                        Db::rollback();
                        return apiResponse(ERROR, 'Failed to insert rejection mail queue');
                    }
                }
            }
            
            // 提交事务
            Db::commit();
            Log::record('[Flow][replyScrapApplyFromSection] Transaction committed successfully');
            return apiResponse(SUCCESS, '[Flow][replyScrapApplyFromSection] success');
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][replyScrapApplyFromSection] Exception caught: ' . $e->getMessage());
            Log::record('[Flow][replyScrapApplyFromSection] Exception trace: ' . $e->getTraceAsString());
            Log::record('[Flow][replyScrapApplyFromSection] Exception file: ' . $e->getFile() . ', line: ' . $e->getLine());
            return apiResponse(ERROR, 'server error: ' . $e->getMessage());
        } catch (Error $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][replyScrapApplyFromSection] Fatal Error caught: ' . $e->getMessage());
            Log::record('[Flow][replyScrapApplyFromSection] Fatal Error trace: ' . $e->getTraceAsString());
            Log::record('[Flow][replyScrapApplyFromSection] Fatal Error file: ' . $e->getFile() . ', line: ' . $e->getLine());
            return apiResponse(ERROR, 'server error: ' . $e->getMessage());
        }
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关/取消
     * @title 样品借出
     * @description 样品借出
     * @method get
     * @param fixed_nos 必选 string fixed_nos=""
     * @return {"status":0,"msg":"[Flow][cancelBorrow] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/cancelBorrow
     * @remark 无
     */
    public function cancelBorrow() {
        try {
            // 前端需要把数组变成字符串
            $fixed_nos = $this->request->param('fixed_nos');// 转为数组

            $query = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos)
                ->where('model_status', BORROW_REVIEW)->find();
            if (!empty($query)) {

                $this->insertLogRecord([
                    'id'=>null,
                    'fixed_no'=>$query['fixed_no'],
                    'desc'=>LOG_DESC_BORROW,
                    'role'=>$this->loginUser['desc'],
                    'operator'=>$query['user_name'],
                    'type'=>LOG_TYPE_APPLY,
                    'result'=>LOG_RESULT_CANCEL,
                    'time'=>Db::raw('now()')
                ]);

                // 更新状态
                $res = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos)
                    ->where('model_status', BORROW_REVIEW)
                    ->update([
                        'user_name'    => null,
                        'user_id'      => null,
                        'model_status' => IN_STORE,
                        'predict_date'  => null
                    ]);

                // 更新不成功
                if (1 != $res) {
                    Log::record('[Flow][cancelBorrow] update fail ' . $fixed_nos);
                    return apiResponse(ERROR, 'server error');
                }
            }
            return apiResponse(SUCCESS, '[Flow][cancelBorrow] success');

        } catch (Exception $e) {
            Log::record('[Flow][cancelBorrow] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');

        }
    }
    /**
     * showdoc
     * @catalog 接口文档/流程相关/取消
     * @title 样品删除/报废
     * @description 样品删除/报废
     * @method get
     * @param fixed_nos 必选 string fixed_nos=[]
     * @return {"status":0,"msg":"[Flow][cancelDeleteScrap] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/cancelDeleteScrap
     * @remark 删除/报废更新的是相同的字段
     */
    public function cancelDeleteScrap() {
        try {
            // 前端需要把数组变成字符串
            $fixed_nos = json_decode($this->request->param('fixed_nos'));// 转为数组

            for ($i = 0; $i < count($fixed_nos); $i++) {

                $query = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                    ->whereIn('model_status', [DELETE_REVIEW, SCRAP_REVIEW])->find();
                if (!empty($query)) {

                    if (DELETE_REVIEW == $query['model_status']) {
                        $desc = LOG_DESC_DELETE;
                    } else {
                        $desc = LOG_DESC_SCRAPE;
                    }
                    $this->insertLogRecord([
                        'id'=>null,
                        'fixed_no'=>$query['fixed_no'],
                        'desc'=>$desc,
                        'role'=>$this->loginUser['desc'],
                        'operator'=>$query['scrap_operator'],
                        'type'=>LOG_TYPE_APPLY,
                        'result'=>LOG_RESULT_CANCEL,
                        'time'=>Db::raw('now()')
                    ]);

                    // 更新状态
                    $res = Db::table('ems_main_engine')->where('fixed_no', $fixed_nos[$i])
                        ->whereIn('model_status', [DELETE_REVIEW, SCRAP_REVIEW])
                        ->update([
                            'model_status'    => IN_STORE,
                            'scrap_operator'      => null,
                            'scrap_date' => null,
                        ]);

                    // 更新不成功
                    if (1 != $res) {
                        Log::record('[Flow][cancelDeleteScrap] update fail ' . $fixed_nos[$i]);
                        return apiResponse(ERROR, 'server error');
                    }
                }
            }
            return apiResponse(SUCCESS, '[Flow][cancelDeleteScrap] success');

        } catch (Exception $e) {
            Log::record('[Flow][cancelDeleteScrap] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');

        }
    }

    private function getSectionAddress($section) {
        $address = array();
        try {
            $subSqlA = Db::table('ems_user')->where('SECTION', $section)
                ->where('IS_DELETED', 0)->buildSql();
            // 查询T系统roleId 为课长
            $subSqlB = Db::table('users')->whereIn('role_id', [T_MANAGER, S_MANAGER, ST_MANAGER])
                ->where('active', 1)->buildSql();

            $res = Db::table($subSqlA . ' a')
                ->join([$subSqlB=> 'b'], 'a.id=b.ems_uid')->field('MAIL')->select();

            foreach ($res as $k => $v) {
                $address[] = $v['MAIL'];
            }
            return $address;
        } catch (Exception $e) {
            Log::record('[Flow][getSectionAddress] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }

    }

    private function getSampleAddress($roleId) {
        $address = array();
        try {
            $subSqlA = Db::table('ems_user')
                ->where('IS_DELETED', 0)->buildSql();

            $subSqlB = Db::table('users')->where('role_id', $roleId)->where('active', 1)->buildSql();

            $res = Db::table($subSqlA . ' a')
                ->join([$subSqlB=> 'b'], 'a.id=b.ems_uid')->field('MAIL')->select();

            foreach ($res as $k => $v) {
                $address[] = $v['MAIL'];
            }
            return $address;
        } catch (Exception $e) {
            Log::record('[Flow][getMachineAdminAddress] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }
    }
     private function insertLogRecordForBorrowApply($data) {
        
        $result=Db::table('ems_log_record')->insert($data);
        if($result){
            return true;
        }else {
            return false;
        }
      

    }
    private function insertLogRecord($data) {
        try {
            Db::table('ems_log_record')->insert($data);

        } catch (Exception $e) {
            Log::record('[Flow][insertLogRecord] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }

    }

    private function updateRejectFlag($fixed_no) {
        try {
            Db::table('ems_main_engine')->where('fixed_no', $fixed_no)->update(['reject_flag' => '1']);

        } catch (Exception $e) {
            Log::record('[Flow][updateRejectFlag] error' . $e->getMessage());
            return apiResponse(ERROR, 'server error');
        }

    }

    /**
     * 根据Java模板确定设备状态
     * @param int $totalNum 总数量
     * @param int $usedNum 使用中数量
     * @param int $scrapNum 报废数量
     * @return int 状态常量
     */
    private function determineModelStatus($totalNum, $usedNum, $scrapNum) {
        Log::record('[Flow][determineModelStatus] Input params - totalNum: ' . $totalNum . ', usedNum: ' . $usedNum . ', scrapNum: ' . $scrapNum);
        
        if ($usedNum > 0 && $usedNum < $totalNum) {
            // 部分使用中
            Log::record('[Flow][determineModelStatus] Returning PART_USING: ' . PART_USING);
            return PART_USING;
        } else if ($usedNum > 0 && $usedNum == $totalNum) {
            // 全部使用中
            Log::record('[Flow][determineModelStatus] Returning USING: ' . USING);
            return USING;
        } else if ($usedNum == 0 && $scrapNum == 0) {
            // 在库
            Log::record('[Flow][determineModelStatus] Returning IN_STORE: ' . IN_STORE);
            return IN_STORE;
        } else if ($usedNum == 0 && $scrapNum > 0 && $scrapNum == $totalNum) {
            // 全部已报废
            Log::record('[Flow][determineModelStatus] Returning SCRAPED: ' . SCRAPED);
            return SCRAPED;
        } else if ($usedNum == 0 && $scrapNum > 0 && $scrapNum < $totalNum) {
            // 部分已报废
            Log::record('[Flow][determineModelStatus] Returning PART_SCRAPED: ' . PART_SCRAPED);
            return PART_SCRAPED;
        } else {
            // 默认状态
            Log::record('[Flow][determineModelStatus] 无法确定状态，使用默认状态IN_STORE。totalNum:' . $totalNum . ', usedNum:' . $usedNum . ', scrapNum:' . $scrapNum);
            return IN_STORE;
        }
    }

    /**
     * showdoc
     * @catalog 接口文档/流程相关/取消
     * @title 取消报废申请
     * @description 取消报废申请
     * @method get
     * @param ems_request_id 必选 string ems_request_id=[]
     * @return {"status":0,"msg":"[Flow][cancelScrapApply] success","data":[]}
     * @url http://domain/ems-api/v1/Flow/cancelScrapApply
     * @remark 1.支持批量取消报废申请; 2.恢复库存和报废数量; 3.根据数量动态确定设备状态
     */
    public function cancelScrapApply() {
        // 开启数据库事务
        Db::startTrans();
        try {
            $userId = $this->loginUser['ems'];
            $ems_request_id_param = $this->request->param('ems_request_id');
            
            // 详细日志记录输入参数
            Log::record('[Flow][cancelScrapApply] start - userId: ' . $userId . ', ems_request_id_param: ' . $ems_request_id_param);
            
            // JSON 参数验证
            $ems_request_id = json_decode($ems_request_id_param, true);
            if (empty($ems_request_id) || !is_array($ems_request_id)) {
                Db::rollback();
                Log::record('[Flow][cancelScrapApply] Invalid ems_request_id parameter: ' . $ems_request_id_param . ', json_last_error: ' . json_last_error());
                return apiResponse(ERROR, 'Invalid ems_request_id parameter');
            }
            
            Log::record('[Flow][cancelScrapApply] ems_request_id array: ' . json_encode($ems_request_id));

            $user = $this->getUserInfoById($userId);
            if (empty($user)) {
                Db::rollback();
                Log::record('[Flow][cancelScrapApply] User not found for userId: ' . $userId);
                return apiResponse(ERROR, 'User not found');
            }
            
            Log::record('[Flow][cancelScrapApply] User info: ' . json_encode($user));
            Log::record('[Flow][cancelScrapApply] Processing request count: ' . count($ems_request_id));
            
            for ($i = 0; $i < count($ems_request_id); $i++) {
                Log::record('[Flow][cancelScrapApply] Processing request ' . ($i+1) . '/' . count($ems_request_id) . ': ' . $ems_request_id[$i]);
                
                $borrowData = $this->getBorrowRequestData($ems_request_id[$i], SCRAP_REVIEW);
                
                if (empty($borrowData)) {
                    Log::record('[Flow][cancelScrapApply] no data for request: ' . $ems_request_id[$i]);
                    continue;
                }
                
                Log::record('[Flow][cancelScrapApply] Found borrowData: ' . json_encode($borrowData));
                
                // 计算恢复后的数量
                $totalNum = $borrowData['total_num'];
                $usedNum = $borrowData['used_num'];
                $borrowNum = $borrowData['borrow_num']; // 从ems_my_borrow获取的报废申请数量
                $newScrapNum = $borrowData['scrap_num'] - $borrowNum; // 恢复报废数量
                
                Log::record('[Flow][cancelScrapApply] Restore calculation - totalNum: ' . $totalNum . ', usedNum: ' . $usedNum . ', borrowNum: ' . $borrowNum . ', newScrapNum: ' . $newScrapNum);
                
                // 根据Java模板确定新状态
                $newStatus = $this->determineModelStatus($totalNum, $usedNum, $newScrapNum);
                
                Log::record('[Flow][cancelScrapApply] Determined new status: ' . $newStatus . ' for fixed_no: ' . $borrowData['fixed_no']);

                // 恢复设备状态和数量
                $res = Db::table('ems_main_engine')
                    ->where('fixed_no', $borrowData['fixed_no'])
                    ->where('model_status', SCRAP_REVIEW)
                    ->update([
                        'scrap_operator'  => null,
                        'scrap_date'      => null,
                        'model_status'    => $newStatus,
                        'inventory_num'   => Db::raw('inventory_num + ' . $borrowNum),
                        'scrap_num'       => Db::raw('scrap_num - ' . $borrowNum)
                    ]);

                Log::record('[Flow][cancelScrapApply] Main engine update result: ' . $res . ' for fixed_no: ' . $borrowData['fixed_no']);

                if (1 !== $res) {
                    Db::rollback();
                    Log::record('[Flow][cancelScrapApply] update fail for request: ' . $ems_request_id[$i] . ', affected rows: ' . $res);
                    return apiResponse(ERROR, 'Failed to restore equipment status');
                }
                
                // 软删除借用记录
                $borrowUpdateResult = Db::table('ems_my_borrow')
                    ->where('ems_request_id', $ems_request_id[$i])
                    ->update(['is_delete' => 1]);
                    
                Log::record('[Flow][cancelScrapApply] Borrow record delete result: ' . $borrowUpdateResult . ' for request: ' . $ems_request_id[$i]);
                    
                if (1 !== $borrowUpdateResult) {
                    Db::rollback();
                    Log::record('[Flow][cancelScrapApply] delete borrow record fail for request: ' . $ems_request_id[$i]);
                    return apiResponse(ERROR, 'Failed to delete borrow record');
                }

                // 记录日志
                $this->insertLogRecord([
                    'id' => null,
                    'fixed_no' => $borrowData['fixed_no'],
                    'desc' => LOG_DESC_SCRAPE,
                    'role' => $this->loginUser['desc'],
                    'operator' => $user['USER_NAME'],
                    'type' => LOG_TYPE_APPLY,
                    'result' => LOG_RESULT_CANCEL,
                    'time' => Db::raw('now()')
                ]);
                
                Log::record('[Flow][cancelScrapApply] Log record inserted for fixed_no: ' . $borrowData['fixed_no']);
            }
            
            // 提交事务
            Db::commit();
            Log::record('[Flow][cancelScrapApply] Transaction committed successfully');
            return apiResponse(SUCCESS, '[Flow][cancelScrapApply] success');
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][cancelScrapApply] Exception caught: ' . $e->getMessage());
            Log::record('[Flow][cancelScrapApply] Exception trace: ' . $e->getTraceAsString());
            Log::record('[Flow][cancelScrapApply] Exception file: ' . $e->getFile() . ', line: ' . $e->getLine());
            return apiResponse(ERROR, 'server error: ' . $e->getMessage());
        } catch (Error $e) {
            // 回滚事务
            Db::rollback();
            Log::record('[Flow][cancelScrapApply] Fatal Error caught: ' . $e->getMessage());
            Log::record('[Flow][cancelScrapApply] Fatal Error trace: ' . $e->getTraceAsString());
            Log::record('[Flow][cancelScrapApply] Fatal Error file: ' . $e->getFile() . ', line: ' . $e->getLine());
            return apiResponse(ERROR, 'server error: ' . $e->getMessage());
        }
    }
}